package com.yuyou.fn.provider.impl;

import com.github.wens.mybatisplus.plugins.Page;
import com.google.common.collect.Collections2;
import com.yuyou.fn.api.CourseClassTradingService;
import com.yuyou.fn.api.dto.*;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.Utils;
import com.yuyou.fn.educational.entity.CourseClass;
import com.yuyou.fn.educational.entity.CourseOrderDiscount;
import com.yuyou.fn.educational.entity.Discount;
import com.yuyou.fn.educational.service.ICourseClassService;
import com.yuyou.fn.educational.service.ICourseOrderDiscountService;
import com.yuyou.fn.educational.service.IDiscountService;
import com.yuyou.fn.portal.entity.OuterOrder;
import com.yuyou.fn.portal.entity.OuterShoppingcart;
import com.yuyou.fn.portal.service.IDiscountQueryService;
import com.yuyou.fn.portal.service.IOuterOrderService;
import com.yuyou.fn.portal.service.IOuterShoppingcartService;
import com.yuyou.fn.portal.vo.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

public class ExposeCourseClassTradingServiceImpl implements CourseClassTradingService {

    @Resource
    private IOuterShoppingcartService shoppingcartService;

    @Resource
    private IOuterOrderService outerOrderService;

    @Resource
    private ICourseClassService courseClassService;

    @Resource
    private IDiscountService discountService;

    @Resource
    private IDiscountQueryService discountQueryService;

    @Resource
    private ICourseOrderDiscountService courseOrderDiscountService;

    @Override
    public OuterShoppingCartDto addToShoppingCart(Long classId, Long userId, Long counselorId) {
        OuterShoppingcart outerShoppingcart = shoppingcartService.addToShoppingCart(classId, userId , counselorId);
        return toOuterShoppingCartDto(outerShoppingcart);
    }

    @Override
    public void deleteShoppingCart(List<Long> outerShoppingCartIds, Long userId) {
        shoppingcartService.deleteShoppingCart(outerShoppingCartIds,userId);
    }

    @Override
    public Long countNumOfShoppingCart(Long userId) {
        return shoppingcartService.countNumByUserId(userId);
    }

    @Override
    public Collection<ShoppingCartDetailDto> findShoppingCartList(Long userId) {
        List<ShoppingCartDetailVo> shoppingCartList = shoppingcartService.findShoppingCartList(userId);
        if(shoppingCartList == null){
            return Collections.EMPTY_LIST;
        }
        return Collections2.transform(shoppingCartList,(shoppingCart) ->{
            ShoppingCartDetailDto shoppingCartDetailDto = new ShoppingCartDetailDto();
            OuterCourseClassDto outerCourseClassDto = new OuterCourseClassDto() ;
            BeanUtils.copyProperties(shoppingCartDetailDto, shoppingCart);
            BeanUtils.copyProperties(outerCourseClassDto,shoppingCart.getCourseClassResultVo());
            shoppingCartDetailDto.setCourseClass(outerCourseClassDto);
            shoppingCartDetailDto.setUserId(userId);
            shoppingCartDetailDto.setOuterShoppingcartId(shoppingCart.getOuterShoppingCartId());
            shoppingCartDetailDto.setClassId(outerCourseClassDto.getClassId());
            return shoppingCartDetailDto;
        });
    }

    @Override
    public Collection<DiscountDetailDto> calDiscountFromShoppingCart(List<Long> outerShoppingCartIds,Long studentId) {
        List<DiscountDetailVo> discountDetailVos = outerOrderService.calDiscountFromShoppingCart(outerShoppingCartIds,studentId);
        if(discountDetailVos == null ){
            return Collections.EMPTY_LIST;
        }
        return Collections2.transform(discountDetailVos,(discountDetailVo) ->{
            DiscountDetailDto discountDetailDto = new DiscountDetailDto() ;
            List<RegClassDiscountExt> regClassDiscounts = discountDetailVo.getRegClassDiscounts();
            discountDetailVo.setRegClassDiscounts(null);
            BeanUtils.copyProperties(discountDetailDto,discountDetailVo);
            if(regClassDiscounts != null ){
                discountDetailDto.setRegClassDiscounts(Collections2.transform(regClassDiscounts,(rcd )->{
                    DiscountDetailDto.RegClassDiscount regClassDiscount = new DiscountDetailDto.RegClassDiscount();
                    BeanUtils.copyProperties(regClassDiscount,rcd );
                    return regClassDiscount ;
                } ));
            }
            return discountDetailDto;
        });
    }

    @Override
    public Collection<DiscountDto> findAvailableDiscountForCourseClass(List<Long> classIds) {

        List<CourseClass> courseClasses = courseClassService.findByIds(classIds, "areaTeamId");
        if(courseClasses == null ){
            return Collections.EMPTY_LIST;
        }

        List<Long> areaTeamIds  = BeanUtils.toList(courseClasses,"areaTeamId");

        Collection<DiscountDto> discountDtos = new ArrayList<>(20);
        for(Long areaTeamId : Utils.unique(areaTeamIds)){
            List<Discount> discounts = discountService.findEffectiveForNetRegByAreaTeamId(areaTeamId);
            if(discounts != null ){
                discountDtos.addAll(Collections2.transform(discounts,(d)->{
                    DiscountDto discountDto = new DiscountDto();
                    BeanUtils.copyProperties(discountDto,d);
                    return discountDto ;
                }));
            }
        }
        return discountDtos;
    }

    @Override
    public Long createOuterOrder(Long classId, Long studentId, Long userId , Long counselorId , String channel) {
        return outerOrderService.createOuterOrder(classId, studentId, userId , counselorId ,channel );
    }



    @Override
    public Long createOuterOrderFromShoppingCart(List<Long> outerShoppingCartIds,Long studentId, Long userId,String channel ) {
        return outerOrderService.createOuterOrderFromShoppingCart(outerShoppingCartIds ,studentId ,userId ,channel );
    }

    @Override
    public PageDto<OuterOrderDetailDto> findOuterOrder(Long userId, int pageNo, int pageSize, List<Integer> chargingStatusList) {
        Page<OuterOrderDetail> page = outerOrderService.findOuterOrder(userId, pageNo, pageSize, chargingStatusList);
        Collection<OuterOrderDetailDto> list  = Collections2.transform( page.getRecords(),this::toOuterOrderDetailDto);
        return new PageDto<>(list,pageNo,pageSize,page.getTotal()) ;
    }

    @Override
    public boolean cancelOrder(Long outerOrderId) {
        outerOrderService.cancelOuterOrder(outerOrderId,4);
        return true;
    }

    @Override
    public OuterOrderDetailDto findOuterOrder(Long outerOrderId) {
        OuterOrderDetail outerOrder = outerOrderService.findOuterOrder(outerOrderId);
        return toOuterOrderDetailDto(outerOrder);
    }

    @Override
    public int findOuterOrderChargingStatus(Long outerOrderId) {
        OuterOrder outerOrder = outerOrderService.findById(outerOrderId, "chargingStatus");
        return outerOrder.getChargingStatus();
    }

    private OuterOrderDetailDto toOuterOrderDetailDto(OuterOrderDetail orderCourseClass) {

        OuterOrderDetailDto outerOrderDetailDto = new OuterOrderDetailDto() ;
        BeanUtils.copyProperties(outerOrderDetailDto,orderCourseClass);
        if(orderCourseClass.getClassInfoList() != null){
            outerOrderDetailDto.setClassInfos(Collections2.transform(orderCourseClass.getClassInfoList(),(c)->{
                OuterOrderDetailDto.ClassInfo classInfo = new OuterOrderDetailDto.ClassInfo();
                OuterCourseClassDto outerCourseClassDto = new OuterCourseClassDto();
                BeanUtils.copyProperties(outerCourseClassDto,c.getCourseClass());
                c.setCourseClass(null);
                BeanUtils.copyProperties(classInfo , c );
                classInfo.setCourseClass(outerCourseClassDto);
                return classInfo;
            }));
        }

        return outerOrderDetailDto;
    }


    private OuterShoppingCartDto toOuterShoppingCartDto(OuterShoppingcart outerShoppingcart) {
        OuterShoppingCartDto outerShoppingCartDto = new OuterShoppingCartDto() ;
        BeanUtils.copyProperties(outerShoppingCartDto,outerShoppingcart);
        return outerShoppingCartDto ;
    }

    @Override
    public void addDiscountCode(Long outerOrderId, String discountCode, Long discountId) {
        outerOrderService.addDiscount(outerOrderId,discountCode,discountId);
    }

    @Override
    public QueryDiscountCodeResultDto queryDiscountCode(Long outerOrderId, String discountCode, Long discountId) {
        QueryDiscountCodeResult discountCodeResult = discountQueryService.queryDiscountCodeResult(outerOrderId, discountCode, discountId);
        QueryDiscountCodeResultDto queryDiscountCodeResultDto=new QueryDiscountCodeResultDto();
        BeanUtils.copyProperties(queryDiscountCodeResultDto,discountCodeResult);
        return queryDiscountCodeResultDto;
    }

    @Override
    public Collection<OrderDiscountItemDto> findByCourseOrderIds(Long outerOrderId) {
        OuterOrder outerOrder = outerOrderService.findById(outerOrderId, "subOrderIds");
        List<CourseOrderDiscount> courseOrderDiscounts = courseOrderDiscountService.findByCourseOrderIds(Utils.toLongIds(outerOrder.getSubOrderIds()));
        Collection<OrderDiscountItemDto> orderDiscountItems = Collections2.transform(courseOrderDiscounts,this::toOrderDiscountItemDto);
        return orderDiscountItems;
    }

    private OrderDiscountItemDto toOrderDiscountItemDto(CourseOrderDiscount courseOrderDiscount){
        OrderDiscountItemDto orderDiscountItemDto = new OrderDiscountItemDto() ;
        BeanUtils.copyProperties(orderDiscountItemDto,courseOrderDiscount);
        return orderDiscountItemDto;
    }
}
